package com.zhentao.ai.algorithm;

import com.zhentao.ai.model.DataPoint;
import com.zhentao.ai.model.ParamUsagePattern;
import com.zhentao.ai.model.PredictionResult;
import com.zhentao.ai.model.UsageRecord;
import com.zhentao.vo.RecommendationVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 智能推荐引擎
 * 基于多维度分析生成参数优化推荐
 * 
 * @author zhentao
 * @date 2024-12-19
 */
@Slf4j
@Component
public class IntelligentRecommendationEngine {
    
    @Autowired
    private ARIMAPredictor arimaPredictor;
    
    @Autowired 
    private SimpleAnomalyDetector simpleAnomalyDetector;
    
    private static final double MIN_CONFIDENCE_THRESHOLD = 0.6;
    private static final int MIN_USAGE_PATTERN_DAYS = 7;
    
    /**
     * 生成智能推荐
     */
    public List<RecommendationVO> generateRecommendations(ParamUsagePattern pattern) {
        if (pattern == null || pattern.getUsageHistory().size() < MIN_USAGE_PATTERN_DAYS) {
            log.warn("使用模式数据不足，无法生成推荐");
            return Collections.emptyList();
        }
        
        log.info("开始生成智能推荐，参数: {}, 历史数据: {}天", 
                pattern.getParamKey(), pattern.getUsageHistory().size());
        
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        // 1. 性能优化推荐
        recommendations.addAll(generatePerformanceRecommendations(pattern));
        
        // 2. 异常预警推荐
        recommendations.addAll(generateAnomalyAlertRecommendations(pattern));
        
        // 3. 趋势预测推荐
        recommendations.addAll(generateTrendPredictionRecommendations(pattern));
        
        // 4. 成本优化推荐
        recommendations.addAll(generateCostOptimizationRecommendations(pattern));
        
        // 5. 安全性推荐
        recommendations.addAll(generateSecurityRecommendations(pattern));
        
        // 6. 过滤和排序
        recommendations = filterAndRankRecommendations(recommendations);
        
        log.info("推荐生成完成，共生成{}条推荐", recommendations.size());
        return recommendations;
    }
    
    /**
     * 性能优化推荐
     */
    private List<RecommendationVO> generatePerformanceRecommendations(ParamUsagePattern pattern) {
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        // 分析使用频率
        double avgUsageFrequency = calculateAverageUsageFrequency(pattern);
        double currentCacheSize = pattern.getCurrentValue() != null ? 
                parseNumericValue(pattern.getCurrentValue()) : 0;
        
        if (avgUsageFrequency > 100 && currentCacheSize < 1000) {
            // 高频使用但缓存较小
            RecommendationVO recommendation = new RecommendationVO();
            recommendation.setParamKey(pattern.getParamKey());
            recommendation.setParamName(pattern.getParamName());
            recommendation.setCurrentValue(pattern.getCurrentValue());
            recommendation.setRecommendedValue(String.valueOf((int)(currentCacheSize * 1.5)));
            recommendation.setRecommendationType("OPTIMIZATION");
            recommendation.setConfidenceScore(calculateConfidenceScore(0.85, pattern));
            recommendation.setRecommendationReason("高频访问检测到，建议增加缓存大小以提升性能");
            recommendation.setExpectedEffect("预计响应时间减少30-50%，系统吞吐量提升25%");
            recommendation.setRiskAssessment("低风险：内存消耗轻微增加，但性能收益显著");
            recommendation.setPriority("HIGH");
            recommendation.setCreateTime(new Date());
            
            recommendations.add(recommendation);
        }
        
        // 分析响应时间趋势
        if (pattern.getPerformanceMetrics() != null) {
            List<Double> responseTimes = pattern.getPerformanceMetrics().getResponseTimes();
            if (isResponseTimeDeteriorating(responseTimes)) {
                RecommendationVO recommendation = createResponseTimeRecommendation(pattern);
                recommendations.add(recommendation);
            }
        }
        
        return recommendations;
    }
    
    /**
     * 异常预警推荐
     */
    private List<RecommendationVO> generateAnomalyAlertRecommendations(ParamUsagePattern pattern) {
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        try {
            // 使用简化版异常检测算法分析使用模式
            List<DataPoint> dataPoints = convertToDataPoints(pattern.getUsageHistory());
            SimpleAnomalyDetector.SimpleAnomalyResult anomalyResult = simpleAnomalyDetector.detectAnomalies(dataPoints);
            
            if (anomalyResult.getAnomalyRate() > 0.1) {
                // 异常率超过10%
                RecommendationVO recommendation = new RecommendationVO();
                recommendation.setParamKey(pattern.getParamKey());
                recommendation.setParamName(pattern.getParamName());
                recommendation.setCurrentValue(pattern.getCurrentValue());
                recommendation.setRecommendationType("ALERT");
                recommendation.setConfidenceScore(calculateConfidenceScore(0.9, pattern));
                recommendation.setRecommendationReason(
                    String.format("检测到异常使用模式，异常率: %.1f%%", 
                                anomalyResult.getAnomalyRate() * 100));
                recommendation.setExpectedEffect("及时发现系统异常，减少故障影响时间");
                recommendation.setRiskAssessment("建议设置监控告警，异常阈值建议设为当前值的±20%");
                recommendation.setPriority("HIGH");
                recommendation.setCreateTime(new Date());
                
                recommendations.add(recommendation);
            }
        } catch (Exception e) {
            log.error("生成异常预警推荐时出错: {}", e.getMessage());
        }
        
        return recommendations;
    }
    
    /**
     * 趋势预测推荐
     */
    private List<RecommendationVO> generateTrendPredictionRecommendations(ParamUsagePattern pattern) {
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        try {
            List<DataPoint> dataPoints = convertToDataPoints(pattern.getUsageHistory());
            if (dataPoints.size() >= 10) {
                PredictionResult prediction = arimaPredictor.predict(dataPoints, 7, 95);
                
                double[] predictions = prediction.getPredictions();
                double currentValue = parseNumericValue(pattern.getCurrentValue());
                double avgPrediction = Arrays.stream(predictions).average().orElse(currentValue);
                
                if (Math.abs(avgPrediction - currentValue) / currentValue > 0.2) {
                    // 预测值与当前值差异超过20%
                    RecommendationVO recommendation = new RecommendationVO();
                    recommendation.setParamKey(pattern.getParamKey());
                    recommendation.setParamName(pattern.getParamName());
                    recommendation.setCurrentValue(pattern.getCurrentValue());
                    recommendation.setRecommendedValue(String.format("%.0f", avgPrediction));
                    recommendation.setRecommendationType("PREDICTION");
                    recommendation.setConfidenceScore(calculateConfidenceScore(0.75, pattern));
                    recommendation.setRecommendationReason(
                        String.format("基于ARIMA模型预测，未来7天平均值预计为%.0f", avgPrediction));
                    recommendation.setExpectedEffect("提前适应负载变化，避免性能瓶颈");
                    recommendation.setRiskAssessment("中等风险：预测模型可能存在偏差，建议逐步调整");
                    recommendation.setPriority("MEDIUM");
                    recommendation.setCreateTime(new Date());
                    
                    recommendations.add(recommendation);
                }
            }
        } catch (Exception e) {
            log.error("生成趋势预测推荐时出错: {}", e.getMessage());
        }
        
        return recommendations;
    }
    
    /**
     * 成本优化推荐
     */
    private List<RecommendationVO> generateCostOptimizationRecommendations(ParamUsagePattern pattern) {
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        // 分析资源利用率
        if (pattern.getResourceUtilization() != null) {
            double avgUtilization = pattern.getResourceUtilization().stream()
                    .mapToDouble(Double::doubleValue)
                    .average()
                    .orElse(0.5);
            
            if (avgUtilization < 0.3) {
                // 利用率低于30%，建议减少资源
                double currentValue = parseNumericValue(pattern.getCurrentValue());
                double recommendedValue = currentValue * 0.7; // 减少30%
                
                RecommendationVO recommendation = new RecommendationVO();
                recommendation.setParamKey(pattern.getParamKey());
                recommendation.setParamName(pattern.getParamName());
                recommendation.setCurrentValue(pattern.getCurrentValue());
                recommendation.setRecommendedValue(String.format("%.0f", recommendedValue));
                recommendation.setRecommendationType("OPTIMIZATION");
                recommendation.setConfidenceScore(calculateConfidenceScore(0.8, pattern));
                recommendation.setRecommendationReason(
                    String.format("资源利用率偏低(%.1f%%)，建议适当减少资源配置", avgUtilization * 100));
                recommendation.setExpectedEffect("预计节省30%的资源成本，性能影响较小");
                recommendation.setRiskAssessment("低风险：可逐步调整，监控性能指标");
                recommendation.setPriority("MEDIUM");
                recommendation.setCreateTime(new Date());
                
                recommendations.add(recommendation);
            }
        }
        
        return recommendations;
    }
    
    /**
     * 安全性推荐
     */
    private List<RecommendationVO> generateSecurityRecommendations(ParamUsagePattern pattern) {
        List<RecommendationVO> recommendations = new ArrayList<>();
        
        // 检查参数值是否存在安全风险
        if (isSecuritySensitive(pattern.getParamKey())) {
            double currentValue = parseNumericValue(pattern.getCurrentValue());
            
            // 连接池/缓存参数安全检查
            if (pattern.getParamKey().contains("pool") || pattern.getParamKey().contains("cache")) {
                if (currentValue > 10000) {
                    RecommendationVO recommendation = new RecommendationVO();
                    recommendation.setParamKey(pattern.getParamKey());
                    recommendation.setParamName(pattern.getParamName());
                    recommendation.setCurrentValue(pattern.getCurrentValue());
                    recommendation.setRecommendedValue("5000");
                    recommendation.setRecommendationType("ALERT");
                    recommendation.setConfidenceScore(calculateConfidenceScore(0.9, pattern));
                    recommendation.setRecommendationReason("参数值过大可能导致资源耗尽，存在DoS攻击风险");
                    recommendation.setExpectedEffect("降低系统被攻击的风险，提高稳定性");
                    recommendation.setRiskAssessment("高风险：建议立即调整并加强监控");
                    recommendation.setPriority("HIGH");
                    recommendation.setCreateTime(new Date());
                    
                    recommendations.add(recommendation);
                }
            }
        }
        
        return recommendations;
    }
    
    /**
     * 过滤和排序推荐
     */
    private List<RecommendationVO> filterAndRankRecommendations(List<RecommendationVO> recommendations) {
        return recommendations.stream()
                .filter(r -> r.getConfidenceScore().compareTo(BigDecimal.valueOf(MIN_CONFIDENCE_THRESHOLD)) >= 0)
                .sorted((r1, r2) -> {
                    // 按优先级和置信度排序
                    int priorityCompare = getPriorityWeight(r1.getPriority()) - getPriorityWeight(r2.getPriority());
                    if (priorityCompare != 0) return -priorityCompare; // 降序
                    return r2.getConfidenceScore().compareTo(r1.getConfidenceScore()); // 降序
                })
                .limit(10) // 最多返回10条推荐
                .collect(Collectors.toList());
    }
    
    // 辅助方法
    private double calculateAverageUsageFrequency(ParamUsagePattern pattern) {
        return pattern.getUsageHistory().stream()
                .mapToDouble(usage -> usage.getAccessCount().doubleValue())
                .average()
                .orElse(0.0);
    }
    
    private BigDecimal calculateConfidenceScore(double baseScore, ParamUsagePattern pattern) {
        // 基于数据质量调整置信度
        double dataQualityFactor = Math.min(1.0, pattern.getUsageHistory().size() / 30.0);
        double adjustedScore = baseScore * dataQualityFactor;
        return BigDecimal.valueOf(adjustedScore).setScale(3, RoundingMode.HALF_UP);
    }
    
    private double parseNumericValue(String value) {
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }
    
    private List<DataPoint> convertToDataPoints(List<UsageRecord> usageHistory) {
        return usageHistory.stream()
                .map(record -> new DataPoint(
                        record.getTimestamp(),
                        record.getAccessCount(),
                        "usage"
                ))
                .collect(Collectors.toList());
    }
    
    private boolean isResponseTimeDeteriorating(List<Double> responseTimes) {
        if (responseTimes.size() < 5) return false;
        
        // 简单趋势分析：比较前半段和后半段的平均值
        int mid = responseTimes.size() / 2;
        double firstHalfAvg = responseTimes.subList(0, mid).stream().mapToDouble(Double::doubleValue).average().orElse(0);
        double secondHalfAvg = responseTimes.subList(mid, responseTimes.size()).stream().mapToDouble(Double::doubleValue).average().orElse(0);
        
        return secondHalfAvg > firstHalfAvg * 1.2; // 后半段比前半段慢20%以上
    }
    
    private RecommendationVO createResponseTimeRecommendation(ParamUsagePattern pattern) {
        RecommendationVO recommendation = new RecommendationVO();
        recommendation.setParamKey(pattern.getParamKey());
        recommendation.setParamName(pattern.getParamName());
        recommendation.setCurrentValue(pattern.getCurrentValue());
        recommendation.setRecommendationType("OPTIMIZATION");
        recommendation.setConfidenceScore(calculateConfidenceScore(0.8, pattern));
        recommendation.setRecommendationReason("检测到响应时间持续增长趋势");
        recommendation.setExpectedEffect("优化参数配置，改善系统响应性能");
        recommendation.setRiskAssessment("建议监控系统负载，考虑增加资源或优化算法");
        recommendation.setPriority("MEDIUM");
        recommendation.setCreateTime(new Date());
        return recommendation;
    }
    
    private boolean isSecuritySensitive(String paramKey) {
        String[] sensitiveKeywords = {"pool", "cache", "timeout", "limit", "max", "buffer"};
        String lowerKey = paramKey.toLowerCase();
        return Arrays.stream(sensitiveKeywords).anyMatch(lowerKey::contains);
    }
    
    private int getPriorityWeight(String priority) {
        switch (priority) {
            case "HIGH": return 3;
            case "MEDIUM": return 2;
            case "LOW": return 1;
            default: return 0;
        }
    }
}
